package com.caffeinatedbliss.nanowrimo.servlet;

import com.caffeinatedbliss.nanowrimo.NanoWebserviceUtils;
import com.caffeinatedbliss.nanowrimo.NanowrimoComputer;
import org.nanowrimo.ws.NanowrimoWebServiceAPI;
import org.nanowrimo.ws.domain.UserSummary;
import org.nanowrimo.ws.domain.WordCountListEntry;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.text.DecimalFormat;
import java.util.*;

/**
 * Created by IntelliJ IDEA.
 * User: pshawke
 * Date: Oct 12, 2006
 * Time: 1:34:22 PM
 * This file was using Monsanto resources and is the sole property of
 * Monsanto.  Any duplication of the code and/or logic is a direct
 * infringement of Monsanto's copyright.
 */
public class ProgressReport extends HttpServlet {
  public static final String TITLE = "NaNoWriMo Progress";
  private String username;

  protected void doGet(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException, IOException {
    doPost(httpServletRequest, httpServletResponse);
  }

  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    response.setContentType("text/html");
    PrintWriter out = response.getWriter();

    String history = getHistoryString(request);
    int goal = getGoal(request);
    NanowrimoComputer computer;
    if (history != null) {
      computer = new NanowrimoComputer(history, goal);
    } else {
      StringTokenizer tok = new StringTokenizer(NanoWebserviceUtils.getFilename(request), "-.");
      if (tok.hasMoreTokens()) {
        int[] counts = getUserCountsFromService(tok.nextToken());
        computer = new NanowrimoComputer(counts, goal);
      } else {
        computer = new NanowrimoComputer("", goal);
      }
    }
    String title = TITLE + (username != null ? (" for " + username) : "");

    int endDay = computer.getEndDay();
    int current = computer.getCurrent();
    int[] historyCounts = computer.getHistoryCounts();
    int[] pace = computer.getPace();
    boolean[] boundries = computer.getBoundries();
    double percentComplete = computer.getPercentComplete();
    int daysLeftNaNoWriMo = computer.getDaysLeftNaNoWriMo();
    int[] expectedDayAmount = computer.getExpectedPerDayAmount();
    int[] paceExpected = computer.getPaceExpected();
    boolean[] outliers = computer.getOutliers();
    int[] expectedWordCount = computer.getExpectedWordCount();

    DecimalFormat twoDigitFormatter = new DecimalFormat("#0.00");

    out.println("<html><head><style><!--");
    writeFile(out, "ProgressReport.css");
    out.print("--></style><title>" + title);
    out.println("</title></head><body>");
    out.println("<h1>" + title + "</h1>");

    out.println("<p>Current word count: " + current + " (" + twoDigitFormatter
      .format(percentComplete) + " %) with " + daysLeftNaNoWriMo + "\n" +
      "  day" + ((daysLeftNaNoWriMo == 1) ? "" : "s") + " left, with current pace, expected to finish in " + endDay + "\n" +
      "  day" + ((endDay == 1) ? "" : "s") + ".</p>");

    out.println("<table cellspacing=\"12\"><tr><td valign=\"top\">");
    out
      .println("<table cellspacing=\"0\" cellpadding=\"0\"><tr><td bgcolor=\"#BBBBBB\"><table cellspacing=\"1\"><tr><th valign=\"bottom\" class=\"heading\">Day</th><th valign=\"bottom\" class=\"heading\">Written</th><th valign=\"bottom\" class=\"heading\">Wordcount</th><th valign=\"bottom\" class=\"heading\">Average<br>Pace</th><th valign=\"bottom\" class=\"heading\">Projected<br>Wordcount</th><th valign=\"bottom\" class=\"heading\">30 Day<br>Expected</th></tr>");

    int running = 0;
    for (int i = 0; i < expectedDayAmount.length; i++) {
      int written = 0;
      boolean useRed = false;
      if (i < historyCounts.length) {
        written = historyCounts[i];
        running += written;
        useRed = true;
      }

      String isOutlier = (outliers[i]) ? "out" : "";
      String writtenColor = (useRed) ? ((written < expectedDayAmount[i]) ? isOutlier + "red" : isOutlier + "green") : isOutlier + "normal";
      String countColor = (useRed) ? ((running < expectedWordCount[i]) ? "red" : "green") : "normal";
      String actualBoundry = (boundries[i]) ? "style=\"border-bottom: 2px solid #000000\"" : "";
      String expected = (expectedDayAmount[i] > 0) ? ("" + expectedDayAmount[i]) : "";
      String avgPace = (pace[i] > 0) ? ("" + pace[i]) : "";
      String paceExp = (paceExpected[i] > 0) ? ("" + paceExpected[i]) : "";
      String actual = (useRed) ? ("" + running) : "";

      out.println("<tr><th  " + actualBoundry + "  class=\"heading\">" + (i + 1) + "</th>");
      out
        .println("<td  " + actualBoundry + "  class=\"" + writtenColor + "\">" + ((written > 0) ? "" + written : "&nbsp;") + "</td>");
      out.println("<td  " + actualBoundry + "  class=\"" + countColor + "\">" + actual + "</td>");
      out.println("<td  " + actualBoundry + "  class=\"normal\" > " + avgPace + " </td> ");
      out.println("<td  " + actualBoundry + "  class=\"normal\" > " + paceExp + " </td> ");
      out.println("<td  " + actualBoundry + "  class=\"normal\" > " + expected + " </td> ");
      out.println("</tr>");
    }

    out.println("</table></td></tr></table>");
    out.println("</td><td valign=\"top\">");
    writeFile(out, "Explanation.html");
    out.println("</td></tr></table>");
    out.println("</body></html>");
  }

  private int[] getUserCountsFromService(String user) {
    WordCountListEntry[] entries = null;
    try {
      NanowrimoWebServiceAPI api = new NanowrimoWebServiceAPI();
      UserSummary userHistory = api.getUserHistory(Integer.parseInt(user));
      username = userHistory.getName();
      entries = userHistory.getEntries();
    } catch (NumberFormatException e) {
    }
    return NanoWebserviceUtils.convertToAmountWritten(entries != null ? entries : new WordCountListEntry[0]);
  }

  private String getHistoryString(HttpServletRequest request) {
    return request.getParameter("history");
  }

  private int getGoal(HttpServletRequest request) {
    String goalStr = request.getParameter("goal");
    int goal = 50000;
    try {
      goal = Integer.parseInt((goalStr == null) ? "50000" : goalStr);
    } catch (NumberFormatException e) {
    }
    return goal;
  }

  private void writeFile(PrintWriter out, String filename) throws IOException {
    InputStream stream = getClass().getResourceAsStream("/com/caffeinatedbliss/nanowrimo/servlet/" + filename);
    InputStreamReader rdr = new InputStreamReader(stream);
    BufferedReader bufferedReader = new BufferedReader(rdr);
    String line = bufferedReader.readLine();
    while (line != null) {
      out.println(line);
      line = bufferedReader.readLine();
    }
  }
}
